#define  _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;

//class Base
//{
//public:
//	virtual void f()
//	{
//		cout << "Base::f()" << endl;
//	}
//	void g()
//	{
//		cout << "Base::g()" << endl;
//	}
//	void h()
//	{
//		cout << "Base::h()" << endl;
//	}
//};
//
//class Derive : public Base
//{
//public:
//	virtual void f()
//	{
//		cout << "Base::f()" << endl;
//	}
//	void g()
//	{
//		cout << "Base::g()" << endl;
//	}
//	void h()
//	{
//		cout << "Base::h()" << endl;
//	}
//
//};

//class Parent {
//public:
//	int iparent;
//	Parent() :iparent(10) {}
//	virtual void f() { cout << " Parent::f()" << endl; }
//	virtual void g() { cout << " Parent::g()" << endl; }
//	virtual void h() { cout << " Parent::h()" << endl; }
//};
//
//class Child : public Parent {
//public:
//	int ichild;
//	Child() :ichild(100) {}
//	virtual void f() { cout << "Child::f()" << endl; }
//	virtual void g_child() { cout << "Child::g_child()" << endl; }
//	virtual void h_child() { cout << "Child::h_child()" << endl; }
//};
//
//class GrandChild : public Child {
//public:
//	int igrandchild;
//	GrandChild() :igrandchild(1000) {}
//	virtual void f() { cout << "GrandChild::f()" << endl; }
//	virtual void g_child() { cout << "GrandChild::g_child()" << endl; }
//	virtual void h_grandchild() { cout << "GrandChild::h_grandchild()" << endl; }
//};
//
//
//int main()
//{
//	//Derive d;
//	//Base* b = new Derive();
//	//b->f();
//
//	GrandChild gc;
//
//
//	return 0;
//}

//class Base1 {
//public:
//	int ibase1;
//	Base1() :ibase1(10) {}
//	virtual void f() { cout << "Base1::f()" << endl; }
//	virtual void g() { cout << "Base1::g()" << endl; }
//	virtual void h() { cout << "Base1::h()" << endl; }
//
//};
//
//class Base2 {
//public:
//	int ibase2;
//	Base2() :ibase2(20) {}
//	virtual void f() { cout << "Base2::f()" << endl; }
//	virtual void g() { cout << "Base2::g()" << endl; }
//	virtual void h() { cout << "Base2::h()" << endl; }
//};
//
//class Base3 {
//public:
//	int ibase3;
//	Base3() :ibase3(30) {}
//	virtual void f() { cout << "Base3::f()" << endl; }
//	virtual void g() { cout << "Base3::g()" << endl; }
//	virtual void h() { cout << "Base3::h()" << endl; }
//};
//
//class Derive : public Base1, public Base2, public Base3 {
//public:
//	int iderive;
//	Derive() :iderive(100) {}
//	virtual void f() { cout << "Derive::f()" << endl; }
//	virtual void g1() { cout << "Derive::g1()" << endl; }
//};

class B
{
public:
	int ib;
	char cb;
public:
	B() :ib(0), cb('B') {}

	virtual void f() { cout << "B::f()" << endl; }
	virtual void Bf() { cout << "B::Bf()" << endl; }
};
class B1 : public B
{
public:
	int ib1;
	char cb1;
public:
	B1() :ib1(11), cb1('1') {}

	virtual void f() { cout << "B1::f()" << endl; }
	virtual void f1() { cout << "B1::f1()" << endl; }
	virtual void Bf1() { cout << "B1::Bf1()" << endl; }

};
class B2 : public B
{
public:
	int ib2;
	char cb2;
public:
	B2() :ib2(12), cb2('2') {}

	virtual void f() { cout << "B2::f()" << endl; }
	virtual void f2() { cout << "B2::f2()" << endl; }
	virtual void Bf2() { cout << "B2::Bf2()" << endl; }

};

class D : public B1, public B2
{
public:
	int id;
	char cd;
public:
	D() :id(100), cd('D') {}

	virtual void f() { cout << "D::f()" << endl; }
	virtual void f1() { cout << "D::f1()" << endl; }
	virtual void f2() { cout << "D::f2()" << endl; }
	virtual void Df() { cout << "D::Df()" << endl; }

};

int main()
{
	typedef void(*Fun)(void);
	int** pVtab = NULL;
	Fun pFun = NULL;

	D d;
	pVtab = (int**)&d;
	cout << "[0] D::B1::_vptr->" << endl;
	pFun = (Fun)pVtab[0][0];
	cout << "     [0] ";    pFun();
	pFun = (Fun)pVtab[0][1];
	cout << "     [1] ";    pFun();
	pFun = (Fun)pVtab[0][2];
	cout << "     [2] ";    pFun();
	pFun = (Fun)pVtab[0][3];
	cout << "     [3] ";    pFun();
	pFun = (Fun)pVtab[0][4];
	cout << "     [4] ";    pFun();
	pFun = (Fun)pVtab[0][5];
	cout << "     [5] 0x" << pFun << endl;

	cout << "[1] B::ib = " << (int)pVtab[1] << endl;
	cout << "[2] B::cb = " << (char)pVtab[2] << endl;
	cout << "[3] B1::ib1 = " << (int)pVtab[3] << endl;
	cout << "[4] B1::cb1 = " << (char)pVtab[4] << endl;

	cout << "[5] D::B2::_vptr->" << endl;
	pFun = (Fun)pVtab[5][0];
	cout << "     [0] ";    pFun();
	pFun = (Fun)pVtab[5][1];
	cout << "     [1] ";    pFun();
	pFun = (Fun)pVtab[5][2];
	cout << "     [2] ";    pFun();
	pFun = (Fun)pVtab[5][3];
	cout << "     [3] ";    pFun();
	pFun = (Fun)pVtab[5][4];
	cout << "     [4] 0x" << pFun << endl;

	cout << "[6] B::ib = " << (int)pVtab[6] << endl;
	cout << "[7] B::cb = " << (char)pVtab[7] << endl;
	cout << "[8] B2::ib2 = " << (int)pVtab[8] << endl;
	cout << "[9] B2::cb2 = " << (char)pVtab[9] << endl;

	cout << "[10] D::id = " << (int)pVtab[10] << endl;
	cout << "[11] D::cd = " << (char)pVtab[11] << endl;

	return 0;
}